// jquery  原生js封装的一个库,快速获取元素,操作元素  (dom的增删改查,事件,ajax,运动)

// 构造函数 传入一个css选择器,返回对应的实例化对象    {eles:[]}
function GetEle(selector) {
    // {}
    // this -> {}

    // 匹配的元素的集合
    this.eles = document.querySelectorAll(selector);

    // this.__proto__ = GetEle.prototype;
    // return this;   // {eles:[]}
}

// 遍历实例化对象中的集合 操作集合中的每一个元素
GetEle.prototype.html = function (con) {
    // this ->指向调用此方法的实例化对象 {eles:[]}
    if (arguments.length >= 1) {  // 有参数
        // for (var i = 0; i < this.eles.length; i++) {
        //     var ele = this.eles[i];
        //     ele.innerHTML = con;
        // }

        // 实例化对象 均可以访问prototype上的方法
        this.each(function (ele) {
            ele.innerHTML = con;
        })
        return this;
    } else { //没有参数
        // 默认返回集合中的第一个(模拟jquery)
        return this.eles[0].innerHTML;
    }
}
GetEle.prototype.text = function (con) {
    if (arguments.length >= 1) {  // 有参数
        // for (var i = 0; i < this.eles.length; i++) {
        //     var ele = this.eles[i];
        //     ele.textContent = con;
        // }
        this.each(function (ele) {
            ele.textContent = con;
        })
        return this;
    } else { //没有参数
        // 默认返回集合中的第一个(模拟jquery)
        return this.eles[0].textContent;
    }
}
GetEle.prototype.val = function (con) {
    if (arguments.length >= 1) {  // 有参数
        // for (var i = 0; i < this.eles.length; i++) {
        //     var ele = this.eles[i];
        //     ele.value = con;
        // }

        this.each(function (ele) {
            ele.value = con;
        })
        return this;
    } else { //没有参数
        // 默认返回集合中的第一个(模拟jquery)
        return this.eles[0].value;
    }
}

GetEle.prototype.hide = function () {
    // this ->指向调用此方法的实例化对象 {eles:[]}
    // for (var i = 0; i < this.eles.length; i++) {
    //     var ele = this.eles[i];
    //     ele.style.display = "none"
    // }
    this.each(function (ele) {
        ele.style.display = "none";
    })
    return this;
}
GetEle.prototype.show = function () {
    // this ->指向调用此方法的实例化对象 {eles:[]}
    // for (var i = 0; i < this.eles.length; i++) {
    //     var ele = this.eles[i];
    //     ele.style.display = "block";
    // }
    this.each(function (ele) {
        ele.style.display = "block";
    })
    return this;
}

// width()  获取和设置元素的宽度
// width("200px")  => 有值,设置
// width()         => 没有值,获取
GetEle.prototype.width = function (con) {
    if (arguments.length >= 1) {
        this.each(function (ele) {

            // 200px pt em rem vw vh %    有单位  直接拼接
            // 200                        没有单位  => 默认px

            var unitReg = /^\d+(px|pt|em|rem|vw|vh|%)$/;
            if (unitReg.test(con)) {
                ele.style.width = con;
            } else {
                ele.style.width = con + "px";
            }

        })
        return this;
    } else {
        // 如果有多个 默认返回第一个
        // return this.eles[0].style.width;     // !!!!!!!!! style获取和设置内联样式

        // return parseFloat(getStyle(this.eles[0], "width"));

        return parseInt(this.getStyle("width"));

    }
}

// width()  获取和设置元素的宽度
// width("200px")  => 有值,设置
// width()         => 没有值,获取
GetEle.prototype.height = function (con) {
    if (arguments.length >= 1) {
        this.each(function (ele) {

            // 200px pt em rem vw vh %    有单位  直接拼接
            // 200                        没有单位  => 默认px

            var unitReg = /^\d+(px|pt|em|rem|vw|vh|%)$/;
            if (unitReg.test(con)) {
                ele.style.height = con;
            } else {
                ele.style.height = con + "px";
            }

        })
        return this;
    } else {
        // 如果有多个 默认返回第一个
        // return this.eles[0].style.height;     // !!!!!!!!! style获取和设置内联样式

        // return parseFloat(getStyle(this.eles[0], "height"));

        return parseInt(this.getStyle("height"));

    }
}


// css()  获取和设置css样式
// css("background","red") 有两个参数,就设置
// css({"background":"red"}) 有一个对象参数,也是设置

// css("background")       只有一个参数,就获取
GetEle.prototype.css = function (key, val) {
    if (arguments.length >= 2) { // key, val
        this.each(function (ele) {
            ele.style[key] = val;
        })
        return this;
    } else if (arguments.length == 1) {  //key
        if (key instanceof Object) {
            //  {
            //     background: "red",
            //     width: "200px",
            //     height: "200px",
            //     float: "left",
            //     textAlign: "center",
            //     lineHeight: "100px",
            // }
            for (var name in key) {
                console.log(name, key[name]);
                // this.each(function (ele) {
                //     ele.style[name] = key[name];
                // })
                this.css(name, key[name]);
            }
            return this;
        } else {
            return this.getStyle(key);
        }
    }
}

// attr()  获取和设置  属性节点 attribute
// attr(key,val)   setAttribite(key,val) 有两个参数,就设置
// attr(key)       getAttribite(key,val) 有一个参数,就获取
GetEle.prototype.attr = function (key, val) {
    // this ->调用此方法的实例化对象 {eles:[]}
    // var key = arguments[0];
    // var val = arguments[1];
    if (arguments.length >= 2) {
        this.each(function (ele) {
            ele.setAttribute(key, val);
        })
        return this;

    } else if (arguments.length == 1) {
        return this.eles[0].getAttribute(key);
    }
}
// prop()  获取和设置元素节点的属性  ele.innerHTML ele.className
// prop(key,val)      有两个参数,就设置
// prop("className", "one")  Element.className = "one"

// prop(key)        有一个参数,就获取
// prop("className")  Element.className 

GetEle.prototype.prop = function (key, val) {
    if (arguments.length >= 2) {
        this.each(function (ele) { // key, val
            ele[key] = val;
        })
        return this;
    } else if (arguments.length == 1) {  //key
        return this.eles[0][key];
    }
}

// GetEle.prototype.addClass = function () {
//     var _arg = arguments;
//     this.each(function (ele) { // key, val
//         ele.classList.add(..._arg);
//     })
//     return this;
// }

// GetEle.prototype.removeClass = function () {
//     var _arg = arguments;
//     this.each(function (ele) { // key, val
//         ele.classList.remove(..._arg);
//     })
//     return this;
// }

GetEle.prototype.addClass = function (con) {
    var list = con.split(" ");
    this.each(function (ele) { // key, val
        ele.classList.add(...list);
    })
    return this;
}

GetEle.prototype.removeClass = function (con) {
    var list = con.split(" ");
    this.each(function (ele) { // key, val
        ele.classList.remove(...list);
    })
    return this;
}
// 链式操作   方法的返回值 依然是一个实例化对象(对应构造函数)
// var arr = [];
// arr.concat(1, 2).concat(3, 4);

// var str = "YY-MM-DD"
// str.replace().replace.replace()

// var p = new Promise(function () { })
// p.then().then().then().catch()


// eq(index)   => 返回对应下标的元素形成的实例化对象 
// $(".list li").eq(0).css({ background: "red" })  =>eq()之后想使用css方法(链式操作) 就意味着 eq()的返回值是一个GelEle实例化对象
GetEle.prototype.eq = function (index) {
    // this.eles[index]
    var ele = this.eles[index]; //对应下标的元素

    // 以前实例化对象 {eles:[li*10]}

    this.eles = [ele];   // eles 存放元素的集合,单元素也要放到集合中

    return this;  // {eles:[]}
}

// siblings()  返回除被选中元素以外 所有的同级元素(形成的实例化对象)
// $(".list li").eq(0).siblings().css({ background: "blue" })
GetEle.prototype.siblings = function (index) {
    var ele = this.eles[0]; // 被选中的元素

    var parentEle = ele.parentElement;  // 被选中的元素的父元素
    var children = parentEle.children; // 父元素中所有的子元素 (包含本身)

    // var arr = [];
    // for (var i = 0; i < children.length; i++) {
    //     var item = children[i];
    //     if (item !== ele) {
    //         arr.push(item);
    //     }
    // }

    var arr = Array.from(children).filter(item => item != ele);  // 除被选中元素以外 所有的同级元素
    this.eles = arr;

    return this;  // {eles:[]}
}



GetEle.prototype.click = function (fn) {
    // this ->指向调用此方法的实例化对象 {eles:[]}   
    // for (var i = 0; i < this.eles.length; i++) {
    //     var ele = this.eles[i];
    //     // ele.onclick = fn;
    //     ele.addEventListener("click", fn);
    // }

    this.each(function (ele) {
        ele.addEventListener("click", fn);
    })
    return this;
}
// 遍历实例化对象中的集合  每次循环时执行传入的回调函数 (item,index)
GetEle.prototype.each = function (fn) {
    // this ->指向调用此方法的实例化对象 {eles:[]}   
    // 元素的集合  this.eles
    for (var i = 0; i < this.eles.length; i++) {
        var item = this.eles[i];
        var index = i;
        fn(item, index);

        // 注意 jquery中 第一个参数是下标,第二个才会循环的当前元素
        // fn(index, item);
    }
    return this;

}
GetEle.prototype.getStyle = function (attr) {
    var ele = this.eles[0]; // 默认返回集合中的第一个
    if (window.getComputedStyle) {
        return window.getComputedStyle(ele)[attr];
    } else {
        return ele.currentStyle[attr];
    }
}


// 获取非行内样式
function getStyle(ele, attr) {
    if (window.getComputedStyle) {
        return window.getComputedStyle(ele)[attr];
    } else {
        return ele.currentStyle[attr];
    }
}



// 对GetEle进行二次封装  => 快速创建实例化对象并返回
function $(selector) {
    return new GetEle(selector);
}